哈囉大家好!今天要帶大家一起來打造一個超酷的鸚鵡鮮食計算機!不管你是不是程式新手,跟著我們一步一步來,保證你也能輕鬆搞定!讓我們一起來看看怎麼用 Nuxt 3 和 Pinia 來完成這個有趣的專案吧!
首先,我們要先設定 API Store。這個 Store 就像是一個神奇的工具箱,裡面放著我們需要的所有工具(也就是 API 函式)。
// stores/api.ts
import { defineStore } from 'pinia'
import axios from 'axios'
const baseURL = 'https://two024it-test-app.onrender.com'
const api = axios.create({
baseURL
})
export const useApiStore = defineStore('api-store', {
actions: {
// 取得食物列表
async fetchFoodList() {
const response = await api.get('/freshfoods/')
return response
},
// * 新增鮮食計算
async calculateFood(data: any) {
const response = await api.post('/foods/calculatefood', data)
return response
}
}
})
這裡我們定義了兩個「動作」(actions):
fetchFoodList
:用來獲取所有可用的鮮食列表。calculateFood
:用來計算特定食物的營養價值。接下來,我們要開始製作計算機的主頁面。這個頁面就像是一個互動式的表單,讓使用者可以輸入資料,然後獲得計算結果。
<!-- pages/calculator.vue -->
<script setup lang="ts">
import { useApiStore } from '~/stores/api'
import { showLoading, hideLoading } from '~/stores/eventBus'
const apiStore = useApiStore()
const foodList = ref([])
// ... 更多程式碼 ...
</script>
<template>
<!-- 這裡放置 HTML 結構 -->
</template>
在這個檔案中,我們:
現在,我們要實作獲取食物列表的功能:
// 取得食物列表
async function fetchFoods() {
try {
showLoading()
const res = await apiStore.fetchFoodList()
const result = res.data
console.log(result)
if (result && result.status === 'success') {
foodList.value = result.data
console.log(foodList.value)
}
} catch (e) {
console.log(e)
} finally {
hideLoading()
}
}
這個函式做了幾件事:
showLoading()
)。foodList
中。hideLoading()
)。昨天有做過,但還是再重複一次,怕有同學漏掉 🙌
接下來是重頭戲,我們要實作計算功能:
// 新增鮮食計算
async function submitCalculatefood() {
try {
showLoading()
const res = await apiStore.calculateFood({
weight: weight.value,
activity: activity.value,
foodId: foodId.value
})
const result = res.data
console.log(result)
if (result && result.status === 'success') {
calculatefoodInfo.value = result.data
console.log('新增成功')
}
} catch (e) {
console.log(e)
} finally {
hideLoading()
}
}
這個函式做的事情有:
calculatefoodInfo
中。最後,我們要把所有東西組合起來,製作一個好用又好看的使用者介面:
<div class="flex-wrapper">
<div class="flex overflow-x-auto">
<div
class="calculator-tab"
:class="{ 'calculator-tab-active': mode === 0 }"
@click="mode = 0"
>
鮮食隨機配
</div>
<div
class="calculator-tab"
:class="{ 'calculator-tab-active': mode === 1 }"
@click="mode = 1"
>
指定鮮食算攝取量
</div>
<div
class="calculator-tab"
:class="{ 'calculator-tab-active': mode === 2 }"
@click="mode = 2"
>
指定熱量算鮮食
</div>
<div
class="calculator-tab"
:class="{ 'calculator-tab-active': mode === 3 }"
@click="mode = 3"
>
指定飼料算攝取量
</div>
<div
class="calculator-tab"
:class="{ 'calculator-tab-active': mode === 4 }"
@click="mode = 4"
>
指定熱量算飼料
</div>
</div>
</div>
這裡有五個標籤,每個都使用了動態類綁定和點擊事件:
:class="{ 'calculator-tab-active': mode === X }"
: 這是一個條件判斷。當 mode
的值等於對應的數字時,標籤會添加 calculator-tab-active
類,用於顯示當前選中的標籤。@click="mode = X"
: 點擊事件,用於切換模式。<div class="cus-border">
<!-- 簡介 -->
<div class="cus-intro">
不知道該給鸚鵡吃什麼嗎?<br />
輸入鸚鵡體重跟活動水平,我幫你推薦營養均衡的鮮食!
</div>
<hr class="cus-line-row" />
<!-- 0 鮮食隨機配 -->
<section v-if="mode === 0" class="">
<div class="cus-block-padding">鮮食隨機配</div>
</section>
<!-- 1 指定鮮食算攝取量 -->
<section v-else-if="mode === 1" class="text-sm sm:text-base">
<!-- 表單內容 -->
</section>
<!-- 2 指定熱量算鮮食 -->
<section v-else-if="mode === 2" class="">
<div class="cus-block-padding">指定熱量算鮮食</div>
</section>
<!-- 3 指定飼料算攝取量 -->
<section v-else-if="mode === 3" class="">
<div class="cus-block-padding">指定飼料算攝取量</div>
</section>
<!-- 4 指定熱量算飼料 -->
<section v-else-if="mode === 4" class="">
<div class="cus-block-padding">指定熱量算飼料</div>
</section>
</div>
這段程式碼實現了一個動態切換內容的鮮食計算機介面:
<div>
使用 cus-border
類來設置整體樣式。cus-intro
類來設置樣式。v-if
和 v-else-if
指令來根據 mode
變數的值動態顯示不同的內容區塊。這實現了單頁面多功能的效果。<section>
標籤中,使用 cus-block-padding
類來設置內邊距。text-sm sm:text-base
類,可能用於響應式文字大小調整。mode
的值,可以輕鬆控制顯示哪個功能區塊。<div class="cus-block-padding">
<h2 class="cus-page-title">輸入基本資料</h2>
<div class="cus-col-3">
<div class="cus-col-1">
<label for="weight" class="cus-label"
>1. 體重 (g) <span class="text-red2">*</span></label
>
<input
type="number"
class="cus-input"
id="weight"
v-model="weight"
placeholder="請輸入鸚鵡體重 (g)"
/>
<span class="cus-input-note">基礎代謝率(BMR) = 175 * (體重 / 1000) ^ 0.75</span>
</div>
<div class="cus-col-1">
<label for="activity" class="cus-label"
>2. 活動水平 <span class="text-red2">*</span></label
>
<div class="cus-radio-row">
<label class="cus-label-radio" for="low">
<input
type="radio"
name="activity"
class=""
id="low"
v-model="activity"
value="low"
/>
<span></span>
低 - 平常不太活動
</label>
<label class="cus-label-radio" for="medium">
<input
type="radio"
name="activity"
class=""
id="medium"
v-model="activity"
value="medium"
/>
<span></span>
中 - 適度活動
</label>
<label for="high" class="cus-label-radio">
<input
type="radio"
name="activity"
class=""
id="high"
v-model="activity"
value="high"
/>
<span></span>高 - 經常活動
</label>
</div>
<span class="cus-input-note">活動水平用來調整 BMR,可以更符合需求</span>
</div>
<div class="cus-col-1" v-if="foodList.length">
<label for="foodId" class="cus-label"
>3. 選擇想計算的食物 <span class="text-red2">*</span></label
>
<select type="number" class="cus-input" id="foodId" v-model="foodId">
<option value="" disabled selected>請選擇食物</option>
<option v-for="food in foodList" :key="food._id" :value="food._id">
{{ food.name }}
</option>
</select>
<span class="cus-input-note">目前僅提供計算資料庫內的食物</span>
</div>
</div>
<button
class="cus-btn-primary mt-5"
:disabled="!weight || !foodId"
@click="submitCalculatefood"
>
開始計算
</button>
</div>
這個表單區域包含了幾個重要的部分:
v-model="weight"
綁定數據。v-model="activity"
綁定數據。v-if="foodList.length"
判斷是否有食物列表,然後使用 v-for
循環顯示選項。:disabled="!weight || !foodId"
判斷是否禁用按鈕。只有當體重和食物ID都有值時,按鈕才能點擊。 <!-- 手機版結果顯示 -->
<div v-if="calculatefoodInfo" class="lg:hidden">
<hr class="cus-line-row" />
<div class="cus-block-padding">
<h2 class="cus-page-title">計算結果</h2>
<!-- ? 每日基本營養需求 -->
<h3 class="cus-title-border-left">每日基本營養需求</h3>
<div class="cus-table mb-5">
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">熱量 (kcal/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.dailyCalories }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">蛋白質 (g/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.dailyProteinNeed }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">脂肪 (g/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.dailyFatNeed }}</div>
</div>
<div class="grid grid-cols-2">
<div class="cus-table-th">碳水化合物 (g/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.dailyCarbsNeed }}</div>
</div>
</div>
<!-- ? 食物營養資訊 -->
<h3 class="cus-title-border-left">食物營養資訊</h3>
<div class="cus-table mb-5">
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">食物名稱</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.name }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">熱量 (kcal/100g)</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.calories }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">蛋白質 (g/100g)</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.protein }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">脂肪 (g/100g)</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.fat }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">碳水化合物 (g/100g)</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.carbs }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">每日最大攝取量 (g/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.maxIntake }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">食物備註</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.note }}</div>
</div>
<div class="grid grid-cols-2">
<div class="cus-table-th">好處</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.nutrition }}</div>
</div>
</div>
<!-- ? 食物建議攝取量 & 營養資訊 -->
<h3 class="cus-title-border-left">食物建議攝取量 & 營養資訊</h3>
<div class="cus-table mb-5">
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">建議攝取量 (g/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.foodIntake }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">蛋白質量 (g/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.protein }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">脂肪量 (g/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.fat }}</div>
</div>
<div class="grid grid-cols-2">
<div class="cus-table-th">碳水化合物量 (g/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.carbs }}</div>
</div>
<div class="cus-table-row grid grid-cols-2">
<div class="cus-table-th">提供總熱量 (kcal/day)</div>
<div class="cus-table-td">{{ calculatefoodInfo.foodProvidedCalories }}</div>
</div>
</div>
<!-- ? 每日所需營養缺失量 -->
<h3 class="cus-title-border-left-err" v-if="calculatefoodInfo.caloriesDifference > 0">
每日所需營養缺失量: {{ calculatefoodInfo.caloriesDifference }} (kcal/day)
</h3>
<h3 v-else class="cus-title-border-left">補充小知識</h3>
<div class="text-blue4">
每日營養最佳分配比例為:<br />
蛋白質 2:脂肪 2:碳水化合物 6,<br />
單一種鮮食難以滿足鸚鵡每日所需營養,<br />
建議可以使用鮮食隨機配!
</div>
</div>
</div>
<!-- 電腦版結果顯示 -->
<div v-if="calculatefoodInfo" class="hidden lg:block">
<hr class="cus-line-row" />
<div class="cus-block-padding">
<h2 class="cus-page-title">計算結果</h2>
<!-- ? 每日基本營養需求 -->
<h3 class="cus-title-border-left">每日基本營養需求</h3>
<div class="cus-table mb-5">
<div class="cus-table-row grid grid-cols-4">
<div class="cus-table-th">熱量 (kcal/day)</div>
<div class="cus-table-th">蛋白質 (g/day)</div>
<div class="cus-table-th">脂肪 (g/day)</div>
<div class="cus-table-th">碳水化合物 (g/day)</div>
</div>
<div class="grid grid-cols-4">
<div class="cus-table-td">{{ calculatefoodInfo.dailyCalories }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.dailyProteinNeed }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.dailyFatNeed }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.dailyCarbsNeed }}</div>
</div>
</div>
<!-- ? 食物營養資訊 -->
<h3 class="cus-title-border-left">食物營養資訊</h3>
<div class="cus-table mb-5">
<div class="cus-table-row grid grid-cols-5">
<div class="cus-table-th">食物名稱</div>
<div class="cus-table-th">熱量 (kcal/100g)</div>
<div class="cus-table-th">蛋白質 (g/100g)</div>
<div class="cus-table-th">脂肪 (g/100g)</div>
<div class="cus-table-th">碳水化合物 (g/100g)</div>
</div>
<div class="grid grid-cols-5">
<div class="cus-table-td">{{ calculatefoodInfo.food?.name }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.calories }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.protein }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.fat }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.carbs }}</div>
</div>
</div>
<div class="cus-table mb-5">
<div class="cus-table-row grid grid-cols-5">
<div class="cus-table-th">每日最大攝取量 (g/day)</div>
<div class="cus-table-th">食物備註</div>
<div class="cus-table-th col-span-3">好處</div>
</div>
<div class="grid grid-cols-5">
<div class="cus-table-td">{{ calculatefoodInfo.food?.maxIntake }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.food?.note }}</div>
<div class="cus-table-td col-span-3">{{ calculatefoodInfo.food?.nutrition }}</div>
</div>
</div>
<!-- ? 食物建議攝取量 & 營養資訊 -->
<h3 class="cus-title-border-left">食物建議攝取量 & 營養資訊</h3>
<div class="cus-table mb-5">
<div class="cus-table-row grid grid-cols-5">
<div class="cus-table-th">建議攝取量 (g/day)</div>
<div class="cus-table-th">蛋白質量 (g/day)</div>
<div class="cus-table-th">脂肪量 (g/day)</div>
<div class="cus-table-th">碳水化合物量 (g/day)</div>
<div class="cus-table-th">提供總熱量 (kcal/day)</div>
</div>
<div class="grid grid-cols-5">
<div class="cus-table-td">{{ calculatefoodInfo.foodIntake }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.protein }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.fat }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.carbs }}</div>
<div class="cus-table-td">{{ calculatefoodInfo.foodProvidedCalories }}</div>
</div>
</div>
<!-- ? 每日所需營養缺失量 -->
<h3 class="cus-title-border-left-err" v-if="calculatefoodInfo.caloriesDifference > 0">
每日所需營養缺失量: {{ calculatefoodInfo.caloriesDifference }} (kcal/day)
</h3>
<h3 v-else class="cus-title-border-left">補充小知識</h3>
<div class="text-blue4">
每日營養最佳分配比例為:<br />
蛋白質 2:脂肪 2:碳水化合物 6,<br />
單一種鮮食難以滿足鸚鵡每日所需營養,<br />
建議可以使用鮮食隨機配!
</div>
</div>
</div>
這段程式碼主要是結果顯示部分,分為手機版和電腦版兩種佈局。主要功能包括:
v-if="calculatefoodInfo"
確保只在有計算結果時顯示內容。lg:hidden
和 hidden lg:block
實現在不同螢幕尺寸下切換顯示版本。calculatefoodInfo
)呈現在畫面上,包括每日基本營養需求、食物營養資訊、建議攝取量等。
pages/calculator.vue
<!-- pages / calculator.vue --> <script setup lang="ts"> import { useApiStore } from '~/stores/api' import { showLoading, hideLoading } from '~/stores/eventBus' const apiStore = useApiStore() const foodList = ref([]) const mode = ref(1) /** * 選擇模式 * 0 鮮食隨機配 * 1 指定鮮食算攝取量 * 2 指定熱量算鮮食 * 3 指定飼料算攝取量 * 4 指定熱量算飼料 */ const weight = ref('') // 體重 const activity = ref('low') // low, medium, high const foodId = ref('') // 食物 ID const calculatefoodInfo: any = ref('') // 指定鮮食算攝取量 onMounted(() => { fetchFoods() }) // 取得食物列表 async function fetchFoods() { try { showLoading() const res = await apiStore.fetchFoodList() const result = res.data console.log(result) if (result && result.status === 'success') { foodList.value = result.data console.log(foodList.value) } } catch (e) { console.log(e) } finally { hideLoading() } } // 新增鮮食計算 async function submitCalculatefood() { try { showLoading() const res = await apiStore.calculateFood({ weight: weight.value, activity: activity.value, foodId: foodId.value }) const result = res.data console.log(result) if (result && result.status === 'success') { calculatefoodInfo.value = result.data console.log('新增成功') } } catch (e) { console.log(e) } finally { hideLoading() } } </script> <template> <div class="w-full"> <!-- * tab --> <div class="flex-wrapper"> <div class="flex overflow-x-auto"> <div class="calculator-tab" :class="{ 'calculator-tab-active': mode === 0 }" @click="mode = 0" > 鮮食隨機配 </div> <div class="calculator-tab" :class="{ 'calculator-tab-active': mode === 1 }" @click="mode = 1" > 指定鮮食算攝取量 </div> <div class="calculator-tab" :class="{ 'calculator-tab-active': mode === 2 }" @click="mode = 2" > 指定熱量算鮮食 </div> <div class="calculator-tab" :class="{ 'calculator-tab-active': mode === 3 }" @click="mode = 3" > 指定飼料算攝取量 </div> <div class="calculator-tab" :class="{ 'calculator-tab-active': mode === 4 }" @click="mode = 4" > 指定熱量算飼料 </div> </div> </div> <!-- * content --> <div class="cus-border"> <!-- * introduction --> <div class="cus-intro"> 不知道該給鸚鵡吃什麼嗎?<br /> 輸入鸚鵡體重跟活動水平,我幫你推薦營養均衡的鮮食! </div> <hr class="cus-line-row" /> <!-- * page > mode --> <!-- ? 0 鮮食隨機配 --> <section v-if="mode === 0" class=""> <div class="cus-block-padding">鮮食隨機配</div> </section> <!-- ? 1 指定鮮食算攝取量 --> <section v-else-if="mode === 1"> <!-- >> 1 指定鮮食算攝取量 info --> <div class="cus-block-padding"> <h2 class="cus-page-title">輸入基本資料</h2> <div class="cus-col-3"> <div class="cus-col-1"> <label for="weight" class="cus-label" >1. 體重 (g) <span class="text-red2">*</span></label > <input type="number" class="cus-input" id="weight" v-model="weight" placeholder="請輸入鸚鵡體重 (g)" /> <span class="cus-input-note">基礎代謝率(BMR) = 175 * (體重 / 1000) ^ 0.75</span> </div> <div class="cus-col-1"> <label for="activity" class="cus-label" >2. 活動水平 <span class="text-red2">*</span></label > <div class="cus-radio-row"> <label class="cus-label-radio" for="low"> <input type="radio" name="activity" class="" id="low" v-model="activity" value="low" /> <span></span> 低 - 平常不太活動 </label> <label class="cus-label-radio" for="medium"> <input type="radio" name="activity" class="" id="medium" v-model="activity" value="medium" /> <span></span> 中 - 適度活動 </label> <label for="high" class="cus-label-radio"> <input type="radio" name="activity" class="" id="high" v-model="activity" value="high" /> <span></span>高 - 經常活動 </label> </div> <span class="cus-input-note">活動水平用來調整 BMR,可以更符合需求</span> </div> <div class="cus-col-1" v-if="foodList.length"> <label for="foodId" class="cus-label" >3. 選擇想計算的食物 <span class="text-red2">*</span></label > <select type="number" class="cus-input" id="foodId" v-model="foodId"> <option value="" disabled selected>請選擇食物</option> <option v-for="food in foodList" :key="food._id" :value="food._id"> {{ food.name }} </option> </select> <span class="cus-input-note">目前僅提供計算資料庫內的食物</span> </div> </div> <button class="cus-btn-primary mt-5" :disabled="!weight || !foodId" @click="submitCalculatefood" > 開始計算 </button> </div> <!-- >> 1 result > md --> <div v-if="calculatefoodInfo" class="lg:hidden"> <hr class="cus-line-row" /> <div class="cus-block-padding"> <h2 class="cus-page-title">計算結果</h2> <!-- ? 每日基本營養需求 --> <h3 class="cus-title-border-left">每日基本營養需求</h3> <div class="cus-table mb-5"> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">熱量 (kcal/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.dailyCalories }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">蛋白質 (g/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.dailyProteinNeed }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">脂肪 (g/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.dailyFatNeed }}</div> </div> <div class="grid grid-cols-2"> <div class="cus-table-th">碳水化合物 (g/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.dailyCarbsNeed }}</div> </div> </div> <!-- ? 食物營養資訊 --> <h3 class="cus-title-border-left">食物營養資訊</h3> <div class="cus-table mb-5"> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">食物名稱</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.name }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">熱量 (kcal/100g)</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.calories }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">蛋白質 (g/100g)</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.protein }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">脂肪 (g/100g)</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.fat }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">碳水化合物 (g/100g)</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.carbs }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">每日最大攝取量 (g/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.maxIntake }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">食物備註</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.note }}</div> </div> <div class="grid grid-cols-2"> <div class="cus-table-th">好處</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.nutrition }}</div> </div> </div> <!-- ? 食物建議攝取量 & 營養資訊 --> <h3 class="cus-title-border-left">食物建議攝取量 & 營養資訊</h3> <div class="cus-table mb-5"> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">建議攝取量 (g/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.foodIntake }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">蛋白質量 (g/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.protein }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">脂肪量 (g/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.fat }}</div> </div> <div class="grid grid-cols-2"> <div class="cus-table-th">碳水化合物量 (g/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.carbs }}</div> </div> <div class="cus-table-row grid grid-cols-2"> <div class="cus-table-th">提供總熱量 (kcal/day)</div> <div class="cus-table-td">{{ calculatefoodInfo.foodProvidedCalories }}</div> </div> </div> <!-- ? 每日所需營養缺失量 --> <h3 class="cus-title-border-left-err" v-if="calculatefoodInfo.caloriesDifference > 0"> 每日所需營養缺失量: {{ calculatefoodInfo.caloriesDifference }} (kcal/day) </h3> <h3 v-else class="cus-title-border-left">補充小知識</h3> <div class="text-blue4"> 每日營養最佳分配比例為:<br /> 蛋白質 2:脂肪 2:碳水化合物 6,<br /> 單一種鮮食難以滿足鸚鵡每日所需營養,<br /> 建議可以使用鮮食隨機配! </div> </div> <!-- <pre> {{ calculatefoodInfo }} </pre> --> </div> <!-- >> 1 result > pc --> <div v-if="calculatefoodInfo" class="hidden lg:block"> <hr class="cus-line-row" /> <div class="cus-block-padding"> <h2 class="cus-page-title">計算結果</h2> <!-- ? 每日基本營養需求 --> <h3 class="cus-title-border-left">每日基本營養需求</h3> <div class="cus-table mb-5"> <div class="cus-table-row grid grid-cols-4"> <div class="cus-table-th">熱量 (kcal/day)</div> <div class="cus-table-th">蛋白質 (g/day)</div> <div class="cus-table-th">脂肪 (g/day)</div> <div class="cus-table-th">碳水化合物 (g/day)</div> </div> <div class="grid grid-cols-4"> <div class="cus-table-td">{{ calculatefoodInfo.dailyCalories }}</div> <div class="cus-table-td">{{ calculatefoodInfo.dailyProteinNeed }}</div> <div class="cus-table-td">{{ calculatefoodInfo.dailyFatNeed }}</div> <div class="cus-table-td">{{ calculatefoodInfo.dailyCarbsNeed }}</div> </div> </div> <!-- ? 食物營養資訊 --> <h3 class="cus-title-border-left">食物營養資訊</h3> <div class="cus-table mb-5"> <div class="cus-table-row grid grid-cols-5"> <div class="cus-table-th">食物名稱</div> <div class="cus-table-th">熱量 (kcal/100g)</div> <div class="cus-table-th">蛋白質 (g/100g)</div> <div class="cus-table-th">脂肪 (g/100g)</div> <div class="cus-table-th">碳水化合物 (g/100g)</div> </div> <div class="grid grid-cols-5"> <div class="cus-table-td">{{ calculatefoodInfo.food?.name }}</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.calories }}</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.protein }}</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.fat }}</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.carbs }}</div> </div> </div> <div class="cus-table mb-5"> <div class="cus-table-row grid grid-cols-5"> <div class="cus-table-th">每日最大攝取量 (g/day)</div> <div class="cus-table-th">食物備註</div> <div class="cus-table-th col-span-3">好處</div> </div> <div class="grid grid-cols-5"> <div class="cus-table-td">{{ calculatefoodInfo.food?.maxIntake }}</div> <div class="cus-table-td">{{ calculatefoodInfo.food?.note }}</div> <div class="cus-table-td col-span-3">{{ calculatefoodInfo.food?.nutrition }}</div> </div> </div> <!-- ? 食物建議攝取量 & 營養資訊 --> <h3 class="cus-title-border-left">食物建議攝取量 & 營養資訊</h3> <div class="cus-table mb-5"> <div class="cus-table-row grid grid-cols-5"> <div class="cus-table-th">建議攝取量 (g/day)</div> <div class="cus-table-th">蛋白質量 (g/day)</div> <div class="cus-table-th">脂肪量 (g/day)</div> <div class="cus-table-th">碳水化合物量 (g/day)</div> <div class="cus-table-th">提供總熱量 (kcal/day)</div> </div> <div class="grid grid-cols-5"> <div class="cus-table-td">{{ calculatefoodInfo.foodIntake }}</div> <div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.protein }}</div> <div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.fat }}</div> <div class="cus-table-td">{{ calculatefoodInfo.nutrientsProvided?.carbs }}</div> <div class="cus-table-td">{{ calculatefoodInfo.foodProvidedCalories }}</div> </div> </div> <!-- ? 每日所需營養缺失量 --> <h3 class="cus-title-border-left-err" v-if="calculatefoodInfo.caloriesDifference > 0"> 每日所需營養缺失量: {{ calculatefoodInfo.caloriesDifference }} (kcal/day) </h3> <h3 v-else class="cus-title-border-left">補充小知識</h3> <div class="text-blue4"> 每日營養最佳分配比例為:<br /> 蛋白質 2:脂肪 2:碳水化合物 6,<br /> 單一種鮮食難以滿足鸚鵡每日所需營養,<br /> 建議可以使用鮮食隨機配! </div> </div> <!-- <pre> {{ calculatefoodInfo }} </pre> --> </div> </section> <!-- ? 2 指定熱量算鮮食 --> <section v-else-if="mode === 2" class=""> <div class="cus-block-padding">指定熱量算鮮食</div> </section> <!-- ? 3 指定飼料算攝取量 --> <section v-else-if="mode === 3" class=""> <div class="cus-block-padding">指定飼料算攝取量</div> </section> <!-- ? 4 指定熱量算飼料 --> <section v-else-if="mode === 4" class=""> <div class="cus-block-padding">指定熱量算飼料</div> </section> <!-- * bottom introduction --> <hr class="cus-line-row" /> <div class="cus-intro"> 推薦食物及計算方式皆由 AI 協助蒐集和整理,僅供參考。<br /> 若有特殊飲食需求建議尋求專業幫助! </div> </div> </div> </template> <style scoped> /* calculator-tab */ .calculator-tab { @apply w-[140px] min-w-[140px] py-[10px] text-center text-[14px] text-blue4 opacity-80; border-left: 1px solid transparent; border-top: 1px solid transparent; border-right: 1px solid transparent; border-radius: 6px 6px 0 0; } .calculator-tab-active { @apply font-bold opacity-100; border-left: 1px solid var(--color-blue4); border-top: 1px solid var(--color-blue4); border-right: 1px solid var(--color-blue4); } .overflow-x-auto { /* 隱藏滾動條的通用方法 */ scrollbar-width: none; /* Firefox */ -ms-overflow-style: none; /* Internet Explorer 10+ */ /* 對於 Webkit (Chrome, Safari, etc.) */ &::-webkit-scrollbar { display: none; } } /* toggle */ .cus-toggle-tab { @apply flex gap-2 rounded-md border border-blue4 p-1 text-[14px]; } .cus-toggle-tab-item { @apply rounded px-3 py-[6px] text-blue4; } .cus-toggle-tab-item-active { @apply bg-blue4 text-blue1; } </style>
stores/api.ts
// stores/api.ts import { defineStore } from 'pinia' import axios from 'axios' const baseURL = 'https://two024it-test-app.onrender.com' const api = axios.create({ baseURL }) export const useApiStore = defineStore('api-store', { actions: { // 取得食物列表 async fetchFoodList() { const response = await api.get('/freshfoods/') return response }, // 新增鮮食計算 async calculateFood(data: any) { const response = await api.post('/foods/calculatefood', data) return response } } })
哇!我們真的做到了!我們一起完成了一個超酷的鸚鵡鮮食計算機。從設定 API、獲取資料、進行計算,到最後呈現結果,我們一步一步地完成了每個環節。
記住,程式設計就像是在搭積木,我們今天學到的每個步驟都是一塊重要的積木。慢慢來,多加練習,你也可以成為一個厲害的程式設計師!
最後,別忘了實際動手試試看喔!實踐是最好的學習方式。加油,你一定可以的!
大家有沒有想要更詳細補充的部分呢?歡迎在下方留言分享喔!讓我們一起在 Nuxt3 的世界中探險吧!加油!
(對了,如果你覺得今天的內容對你有幫助,別忘了給個讚支持一下喔!這會是我繼續努力的動力呢~)